import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False  # 用 ASCII 减号替代 Unicode 减号



df =pd.read_csv('data/ccf_offline_stage1_train.csv',parse_dates=['Date_received','Date'])
print(df.info())
df



df.isnull().sum()


#把折扣列的满减全部转换为折扣率统一形式
df['Discount_rate'] = df['Discount_rate'].fillna('null')

def rate_convert(data):
    if data == 'null':
        return np.nan
    elif ':'in data:
        temp = data.split(':')
        rate = (float(temp[0]) - float(temp[1]))/float(temp[0])
        return '{:.2f}'.format(rate)
    else:
        return data

df['Discount_rate'] = df['Discount_rate'].map(rate_convert)
df


#是否 优惠卷id,接受日期，折扣率空值和非空值是否一一对应

#利用 np.all() 判断一个可迭代数据中是否都为True

nan1 = df['Coupon_id'].isnull()
nan2 = df['Discount_rate'].isnull()
nan3 = df['Date_received'].isnull()

np.all((nan1==nan2) & (nan2 ==nan3))


#用户类型标识  消费用卷  消费不用卷  有卷不消费  无卷不消费

def judge_type(data):
    if pd.isnull(data['Date']):
        if pd.isnull(data['Coupon_id']):
            return "noconsume_nocoupon"
        else:
            return "noconsume_hascoupon"
    else:
        if pd.isnull(data['Coupon_id']):
            return "hasconsume_nocoupon"
        else:
            return "hasconsume_hascoupon"

df['Type'] = df.apply(judge_type,axis=1)
df



user_type = df['Type'].value_counts()
user_type



# noconsume_hascoupon = df[df['Coupon_id'].notnull() & df['date'].isnull()]  #另一种获取每种类型用户的方法


plt.figure(figsize=(12,6))
plt.pie(df['Type'].value_counts(),autopct="%1.1f%%",shadow=True,explode=[0.02,0.05,0.02],textprops={'fontsize':15,'color':'blue'},
        wedgeprops={'linewidth':1,'edgecolor':'black'},
        labels=[user_type.loc['noconsume_hascoupon'],user_type.loc['hasconsume_nocoupon'],user_type.loc['hasconsume_hascoupon']])

plt.legend(['noconsume_hascoupon','hasconsume_nocoupon ','hasconsume_hascoupon'])
plt.show()


# 在有卷消费人群中，分析他们用卷的原因，是距离近还是折扣大

hasconsume_hascoupon = df[df['Type'] == 'hasconsume_hascoupon'].copy()  #不适用copy 返回一个 视图（View） 而非独立的副本（Copy）这页后续赋值操作可能受到影响
hasconsume_hascoupon


merchant_distance_mean = hasconsume_hascoupon.groupby('Merchant_id')['Distance'].mean()
print(len(merchant_distance_mean[merchant_distance_mean == 0]))  #平均消费距离在500以内的商家数
merchant_distance_mean


#hasconsume_hascoupon.loc[:,'Discount_rate']= hasconsume_hascoupon['Discount_rate'].astype(float)
hasconsume_hascoupon['Discount_rate']= pd.to_numeric(hasconsume_hascoupon['Discount_rate'], errors='coerce')

print(hasconsume_hascoupon['Discount_rate'].dtype)
merchant_rate_mean = round(hasconsume_hascoupon.groupby('Merchant_id')['Discount_rate'].mean(),2)
print(merchant_rate_mean.mean())
merchant_rate_mean


merchant_rate_mean.hist()
plt.show()


#持卷到店消费人数最多的商家
popular_merchanrt = hasconsume_hascoupon.groupby('Merchant_id')['User_id'].apply(lambda x: len(x.unique())).sort_values(ascending=False)
#print(hasconsume_hascoupon.groupby('Merchant_id')['User_id'].apply(lambda x: x.drop_duplicates().count()).sort_values(ascending=False)) 方式二
popular_merchanrt


#持卷到店消费人数前500名
popular_merchanrt500 = popular_merchanrt[popular_merchanrt > 500]
print(len(popular_merchanrt500))
print(type(popular_merchanrt500))
print(popular_merchanrt500.to_frame())
popular_merchanrt500


#研究这批商家是如何使用消费卷的，他们的折扣力度和平均距离
popular_merchanrt500.name = 'Cosumer_count'
merchant_pop_dis=  pd.merge(left=popular_merchanrt500,right=merchant_distance_mean,on="Merchant_id",how="inner")
merchant_pop_dis_and_rate = pd.merge(left=merchant_pop_dis,right=merchant_rate_mean,on="Merchant_id",how="inner")
merchant_pop_dis_and_rate



# 计算到店消费人数与平均距离和折扣力度的相关系数
# corr函数  皮尔逊相关系数

merchant_pop_dis_and_rate.corr()



#用热力图展示相关系数 seaborn库

sns.heatmap(data=merchant_pop_dis_and_rate.corr(),cmap='RdBu_r',annot=True,vmax=1,vmin=-1,linewidths=1)  #annot 显示相关系数的数值

plt.show()


#发卷量和用卷量分析

coupon_send = df[df['Date_received'].notnull()]
coupon_send = coupon_send.groupby("Date_received")['User_id'].count()
coupon_send.rename("count")
coupon_send






#每天用卷量分析
coupon_use = df[df['Date'].notnull() & df['Coupon_id'].notnull()]
coupon_use = coupon_use.groupby("Date_received")['User_id'].count()
coupon_use.rename("count")
coupon_use





#绘制每天发卷量和用卷量
plt.figure(figsize=(18,8))


coupon_send.plot.bar(label='每天发卷量',color='orange')
coupon_use.plot.bar(label='每天用卷量')
plt.legend()
plt.yscale('log')
plt.tight_layout()
plt.show()


#计算每天的优惠卷与发卷量占比

plt.figure(figsize=(18,6))
x_sort = df[df['Date_received'].notnull()]['Date_received'].sort_values().unique()
print(x_sort)

plt.bar(x=x_sort,height=coupon_use/coupon_send,label='使用量占比')
plt.show()



